local ClientOHOH = _G.ClientOHOH;
local M = ClientOHOH.class.new(script, ClientOHOH.files.BaseComponent());
local CallBackManager = ClientOHOH.load.CallBackManager();

local InstanceManager = ClientOHOH.load.InstanceManager();
local BigNumberHelper = ClientOHOH.load.BigNumberHelper();

local SHOOTID=0

function M.new(self,...)
	return M(self,...);
end;

function M.ctor(self, parent)
	M.super.ctor(self, parent);

    self.bullet_list={}
    self.ConList={} --监听模拟器
    self.player=_G.client.local_player

    self:InitAttackInfo()
    self:ListenShoot()
end;

-- 初始化攻击者信息(子类必须重写)
function M.InitAttackInfo(self)
    self.DameHpUi="UI.WeaponDamage"
    self.actionId="PlayerAttack"
    self.attcaker=self.player:GetUserId()
end



-- 监听开始射击(子类必须重写)
function M.ListenShoot(self)

end
-- 获取伤害值(子类必须重写)
function M.GetDamge(self)
    return  self.player:GetAttackDamage()
end

-- 获取子弹Id(子类必须重写)
function M.GetBulletId(self)
    return "Gloves_Bullet_1"
end
-- 将伤害推送至服务器(子类必须重写)
function M.PushDamge2Server(self,lvId,mId)

end

 -- 获取子弹的朝向(子类必须重写)
 function M.GetBulletStartCFrame(self,pos)
    if pos then
        self.parent:SetLookAt(pos)
    end
    return self.parent:GetCFrame()
end

-- 子弹是否穿透
function M.IsPenetrate(self)
    return false
end

--子弹移动速度
function M.GetBulletSpeed(self) 
    return 100
end
--子弹存在时间
function M.GetBulletLifeTime(self)
    return 4
end

-- 寻找射击位置
function M.FindShootPos(self)

end


function M.DtorBullet(self)
    for id, b in pairs(self.bullet_list) do
        b:dtor()
    end
    self.bullet_list={}
end

-- 射击一次
function M.Shoot(self)
    local b=self:CreateBullet()
	self.bullet_list[b.id]=b
	self:StartWeaponUpdate()
end

function M.MonsterHurtShow(self,damage,attacker,m)
    -- local root=_G.POOL:GetObj(self.DameHpUi)
    -- root.Parent=workspace
    -- root.Position=m:GetPosition()+Vector3.new(math.random(-10,10),math.random(2,6),math.random(-10,10))

    -- root.UI.Frame.TextLabel.Text="-"..BigNumberHelper:ToString(damage)
    -- require(root.UI.Frame.TextLabel.Animator).NewTween:Play()
    -- delay(0.3,function()
    --     _G.POOL:PushObj(self.DameHpUi,root)
    -- end)
end


function M.CreateBullet(self)
    local apos=self:FindShootPos()

    local cf=self:GetBulletStartCFrame(apos)

    local look=cf.LookVector --CFrame.lookAt(Vector3.zero,cf.LookVector,cf.UpVector) 
    local pos=cf.Position

    local direction=look.Unit

    local bulletId=self:GetBulletId()
    local bullet= _G.POOL:GetObj(bulletId)

   bullet:SetPrimaryPartCFrame(cf)
    local a= {
        BulletId=bulletId,
        StartCF=cf,
        Obj=bullet,
		Speed=self:GetBulletSpeed(),
        Direction=direction,
        IsPenetrate=self:IsPenetrate(),
        NowPos=pos,
        id=SHOOTID,
        BornTime=os.clock(),
        LifeTime=self:GetBulletLifeTime(),
        Lenght=0,
		Update=function(this,dt)
            this.Lenght=this.Lenght+this.Speed*dt
            bullet:SetPrimaryPartCFrame(this.StartCF+this.Direction*this.Lenght)
		end,

        dtor=function(this)
            if this.touchConenct then
                this.touchConenct:Disconnect()
                this.touchConenct=nil
            end
            _G.POOL:PushObj(this.BulletId,this.Obj)
        end,

        IsOver=function(this)
            return os.clock()- this.BornTime>this.LifeTime
        end,

        Init=function(this)
            this["touchConenct"]=this.Obj.touch.Touched:Connect(function(tp)   
                if tp.Name== "Touch" and tp.Parent and  tp.Parent.Name=="Monster" then

               
                        local monster = InstanceManager:FindObject(tp.Parent);
                        if not monster then
                            return  
                        end
                        local damage,isKill=self:GetDamge()

                        monster:Hurt(damage,self.parent,isKill,function(hp,oldHp,attacker,m)
                            local lid,mid=m:GetLevelIdAndMonsterId()
                            self:PushDamge2Server(lid,mid)
                            self:MonsterHurtShow(damage,attacker,m)
                        end)
                        if not this.IsPenetrate then
                            self.bullet_list[this.id]=nil
                            this:dtor()
                        end
                    end
            end)
        end,
    }
    SHOOTID=SHOOTID+1
    a:Init()
    return a
end

function M.StartWeaponUpdate(self)
	if self.__Weapon_update_cnnt then
		return;
	end;
	self.__Weapon_update_cnnt = self:AddRenderUpdate("render", self.WeaponShowUpdate);
end;

function M.StopWeaponUpdate(self)
	if self.__Weapon_update_cnnt then
		self.__Weapon_update_cnnt:Disconnect();
		self.__Weapon_update_cnnt = nil;
	end;
end;

function M.WeaponShowUpdate(self,dt)

    local idList={}
    local had=false
	for id, b in pairs(self.bullet_list) do
        b:Update(dt)
        if b:IsOver() then
            b:dtor()
            table.insert(idList,id)
        else
            had=true
        end
	end;

    for _,id in pairs(idList) do
        self.bullet_list[id]=nil
    end
    if not had then
        self:StopWeaponUpdate()
        return true
    end
end;

function M.dtor(self)
    self:DtorBullet()
    for _,con in pairs(self.ConList) do
        con:Disconnect()
    end
    self.ConList={}
	M.super.dtor(self);
end;

return M